package com.syx.server.service;

import com.syx.common.Message;
import com.syx.common.MessageType;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.HashMap;
import java.util.Iterator;

/**
 * @author 邵一鑫
 * @date 2024/1/13 22:5
 * 该线程用于持有 server 和 client 连接的 socket
 */
public class ServerConnectClientThread extends Thread{

    private String userId;
    private Socket socket = null;

    public ServerConnectClientThread() {}

    public ServerConnectClientThread(String userId, Socket socket) {
        this.userId = userId;
        this.socket = socket;
    }

    @Override
    public void run() {
        System.out.println("与用户" + userId + "的连接已建立...");
        boolean loop = true;
        while (loop) {
            try {
                // 得到 ObjectInputStream
                ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                // 定义输出流
                ObjectOutputStream oos;
                // 如果没有消息，会在这里阻塞
                Message message = (Message)ois.readObject();
                switch (message.getMesType()) {
                    // 返回在线用户列表
                    case MessageType.MESSAGE_GET_ONLINE_FRIEND:
                        // 得到 ObjectOutputStream
                        oos = new ObjectOutputStream(socket.getOutputStream());
                        // 写入
                        oos.writeObject(new Message(ManageConnectClientThread.getOnlineUser(), MessageType.MESSAGE_RET_ONLINE_FRIEND));
                        break;
                    // 客户端请求退出
                    case MessageType.MESSAGE_CLIENT_EXIT:
                        String userId = message.getFromUser();
                        System.out.println(userId + "请求断开连接...");
                        // 将线程从集合中移除
                        ManageConnectClientThread.removeThread(userId);
                        // 关闭当前线程持有的 socket
                        socket.close();
                        // 退出线程
                        loop = false;
                        break;
                    // 接收私聊信息并转发
                    case MessageType.MESSAGE_COMM_MES:
                        String fromUser = message.getFromUser();
                        String toUser = message.getToUser();
                        String content = message.getContent();
                        String sendTime = message.getSendTime();
                        // 获取转发的 ObjectOutputStream
                        oos = new ObjectOutputStream(
                                ManageConnectClientThread.getServerConnectClientThread(toUser).getSocket().getOutputStream());
                        // 分装新的Message并发送
                        oos.writeObject(new Message("[" + sendTime + "]" + fromUser + "对" + toUser + "说：" + content, MessageType.MESSAGE_COMM_MES));
                        break;
                    // 接收群发信息并转发
                    case MessageType.MESSAGE_TO_ALL:
                        // 遍历集合中的所有线程，除了消息的发送者，分别发送信息
                        HashMap<String, ServerConnectClientThread> users = ManageConnectClientThread.getThreadMap();
                        Iterator iterator = users.keySet().iterator();
                        while (iterator.hasNext()) {
                            // 获取id
                            String onlineUserId = iterator.next().toString();
                            if (!onlineUserId.equals(message.getFromUser())) {
                                // 转发
                                oos = new ObjectOutputStream(
                                        users.get(onlineUserId).getSocket().getOutputStream());
                                oos.writeObject(new Message("[" + message.getSendTime() + "]" + message.getFromUser() + "对大家说：" + message.getContent(), MessageType.MESSAGE_COMM_MES));
                            }
                        }
                        break;
                    // 接收文件并转发
                    case MessageType.MESSAGE_FILE:
                        oos = new ObjectOutputStream(
                                ManageConnectClientThread.getServerConnectClientThread(message.getToUser()).getSocket().getOutputStream());
                        // 转发
                        oos.writeObject(message);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

        }
    }

    public Socket getSocket() {return socket;}
}
